/*
 * OREKIT-X
 * Copyright 2002-2008 CS Communication & Systemes
 * 
 * Parts of this software package have been licensed to CS
 * Communication & Systemes (CS) under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work for
 * additional information.
 *  
 * This is an experimental copy of OREKIT from www.orekit.org.
 * Please use the original OREKIT from orekit.org for normal work
 * unrelated to this research project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You
 * may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package ore.propagation;

import ore.propagation.events.EventDetector;
import ore.propagation.sampling.OrekitFixedStepHandler;
import ore.propagation.sampling.OrekitStepHandler;

import java.util.Collection;

/** 
 * This interface is the abstraction for orbit propagation.
 * 
 * It is implemented by analytical models which have no time limit, by
 * orbit readers based on external data files, by numerical
 * integrators using rich force models and by continuous models built
 * after numerical integration has been completed and dense output
 * data as been gathered.
 * 
 * @author Luc Maisonobe
 * @author V&eacute;ronique Pommier-Maurussane
 */
public interface Propagator
    extends BasicPropagator
{
    /** 
     * Indicator for slave mode.
     */
    public final static int SLAVE_MODE = 0;
    /** 
     * Indicator for master mode.
     */
    public final static int MASTER_MODE = 1;
    /** 
     * Indicator for ephemeris generation mode.
     */
    public final static int EPHEMERIS_GENERATION_MODE = 2;

    /** 
     * @param detector event detector to add
     */
    public void addEventDetector(final EventDetector detector);
    /** 
     * @return A copy of the collection of event detectors
     */
    public Collection<EventDetector> getEventsDetectors();
    /** 
     * Remove all events detectors.
     */
    public void clearEventsDetectors();
    /** 
     * Get the current operating mode of the propagator.
     * 
     * @return One of {@link #SLAVE_MODE}, {@link #MASTER_MODE},
     * {@link #EPHEMERIS_GENERATION_MODE}
     */
    public int getMode();
    /** 
     * Set the propagator to slave mode.
     * 
     * This mode is used when the user needs only the final orbit at the target time.
     * The (slave) propagator computes this result and return it to the calling
     * (master) application, without any intermediate feedback.
     * 
     * This is the default mode.
     */
    public void setSlaveMode();
    /** 
     * Set the propagator to master mode with fixed steps.
     * 
     * This mode is used when the user needs to have some custom
     * function called at the end of each finalized step during
     * integration. The (master) propagator integration loop calls the
     * (slave) application callback methods at each finalized step.
     * 
     * @param h Fixed stepsize (s)
     * @param handler Handler called at the end of each finalized step
     */
    public void setMasterMode(double h, OrekitFixedStepHandler handler);
    /** 
     * Set the propagator to master mode with variable steps.
     * 
     * This mode is used when the user needs to have some custom
     * function called at the end of each finalized step during
     * integration. The (master) propagator integration loop calls the
     * (slave) application callback methods at each finalized step.
     * 
     * @param handler handler called at the end of each finalized step
     */
    public void setMasterMode(OrekitStepHandler handler);
    /** 
     * Set the propagator to ephemeris generation mode.
     * 
     * This mode is used when the user needs random access to the orbit state at any time
     * between the initial and target times, and in no sequential order. A typical example is
     * the implementation of search and iterative algorithms that may navigate forward and
     * backward inside the propagation range before finding their result.
     * 
     * Beware that since this mode stores <strong>all</strong> intermediate results,
     * it may be memory intensive for long integration ranges and high precision/short
     * time steps.
     */
    public void setEphemerisMode();
    /** 
     * @return Ephemeris generated during propagation
     * 
     * @exception IllegalStateException Propagator was not set in
     * ephemeris generation mode before propagation
     */
    public BoundedPropagator getGeneratedEphemeris() throws IllegalStateException;

}
